package com.drpclub.gamebackend.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.drpclub.gamebackend.bean.ContentHtml;
import com.drpclub.gamebackend.bean.Resources;
import com.drpclub.gamebackend.common.utils.FileUtils;
import com.drpclub.gamebackend.dao.ResourceDao;
import com.drpclub.gamebackend.exception.MyAccessException;
import com.drpclub.gamebackend.repository.ResourceRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import static com.drpclub.gamebackend.common.constant.Const.*;
import static com.drpclub.gamebackend.common.utils.DrpUtils.isNotNull;
import static com.drpclub.gamebackend.common.utils.DrpUtils.verifyImageType;
import static com.drpclub.gamebackend.common.utils.FileUtils.*;
import static com.drpclub.gamebackend.common.utils.JwtUtils.getUsernameFromToken;

/**
 * @author ：drp
 * @date ：Created in 2020/5/11 22:04
 */
@Slf4j
@Service
public class ContentService {
    @Resource
    private ResourceRepository resRepository;

    @Resource
    private FileUtils fileUtils;

    public String uploadContentImage(MultipartFile image, String contentId, String token) throws IOException {
        //check file security
        final String username = getUsernameFromToken (token);

        final String type = verifyImageType (image.getInputStream ());

        final String filePath = fileUtils.getFileSaveRealPath (CONTENT_IMAGE_PATH, true) +
                "/" + username + "/" + contentId;
        final String filename = System.currentTimeMillis () + "." + type;

        transMultipartFileTo (image, filename, filePath);
        return fullFilePath (getContentImgPath (filename, contentId, username));
    }

    @Transactional(transactionManager = TRANSACTION_MANAGER, rollbackFor = {Exception.class})
    public ResourceDao createResource(Resources res, String token) throws IOException {
        final String username = isNotNull (getUsernameFromToken (token), "用户名");
        //TODO 以后添加对用户创建资源的其他操作 等级、 vip 类型等

        final ResourceDao resDetails = new ResourceDao ();
        resDetails.setUsername (username);
        BeanUtil.copyProperties (res, resDetails, CopyOptions.create ().setIgnoreNullValue (true));
        ResourceDao resourceDao = resRepository.save (resDetails);

        createContentHtml (new ContentHtml (resourceDao.getId (), ""), token);
        return resourceDao;
    }

    public String uploadCoverImage(MultipartFile image, String token) throws IOException {
        final String username = isNotNull (getUsernameFromToken (token), "用户名");
        final String type = verifyImageType (image.getInputStream ());
        final String filePath = fileUtils.getFileSaveRealPath (COVER_IMAGE_PATH, true) + "/" + username;
        final String filename = System.currentTimeMillis () + "." + type;
        transMultipartFileTo (image, filename, filePath);
        return fullFilePath (getCoverImgPath (filename, username));
    }

    public List<String> getCollectionNames(String token) {
        final String username = isNotNull (getUsernameFromToken (token), "用户名");
        return resRepository.findCollectionNameByUsername (username);
    }

    public List<ResourceDao> getResource(String title, String token) {
        final String username = isNotNull (getUsernameFromToken (token), "用户名");
        return resRepository.findResourceDaoByCollectionNameAndUsername (title, username);
    }

    public boolean createContentHtml(ContentHtml content, String token) throws IOException {
        final String username = isNotNull (getUsernameFromToken (token), "用户名");
        final String filepath = fileUtils.getFileSaveRealPath (CONTENT_ESSAY_PATH, true) + "/" + username;
        final String fileName = content.getContentId () + ".html";

        File file = new File (filepath + "/" + fileName);
        File parentFile = file.getParentFile ();
        if (!parentFile.exists ()) {
            parentFile.mkdirs ();
        }
        if (!file.exists ()) {
            file.createNewFile ();
        }
        try (FileOutputStream os = new FileOutputStream (file)) {
            os.write (content.getValue ().getBytes ());
        }
        return true;
    }

    @Transactional(transactionManager = TRANSACTION_MANAGER, rollbackFor = {Exception.class})
    public boolean publishContentHtml(ContentHtml content, String token) {
        final String username = isNotNull (getUsernameFromToken (token), "用户名");
        if(!username.equals(resRepository.findUsernameById(content.getContentId()))) {
            //TODO 恶意攻击， 应当把相应的ip加入黑名单
            throw new MyAccessException ("用户权限不足");
        }
        resRepository.updatePublishByContentId(content.getIsPublish(), content.getContentId());
        return true;
    }

    @Transactional(transactionManager = TRANSACTION_MANAGER, rollbackFor = {Exception.class})
    public boolean changeContentTitle(String contentId, String title, String token) {
        final String username = isNotNull (getUsernameFromToken (token), "用户名");
        if(!username.equals(resRepository.findUsernameById(contentId))) {
            //TODO 恶意攻击， 应当把相应的ip加入黑名单
            throw new MyAccessException ("用户权限不足");
        }
        return resRepository.updateTitleByContentId(title, contentId) > 0;
    }
}
